package nc.impl.hrppl.pjapplication.pjappl;

import nc.bs.dao.BaseDAO;
import nc.bs.hrppl.util.ListMapSorter;
import nc.codeplatform.framework.commons.DaoUtils;
import nc.itf.hrppl.pjapplication.pjappl.IPJApplDefService;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.vo.hrppl.pjapplication.AggPjapplVO;
import nc.vo.hrppl.pjapplication.PJApplHVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PJApplDefServiceImpl implements IPJApplDefService {
    private BaseDAO baseDAO;
    protected DaoUtils dao;

    @Override
    public void pjApplApprove(AggPjapplVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) return;
        List<AggPjapplVO> laggvos = new ArrayList<>();
        for (AggPjapplVO vo : vos) {

            PJApplHVO hvo = vo.getParentVO();
            hvo.setStatus(VOStatus.UPDATED);
            String officedept = hvo.getOfficedept();// 业务科室
            Object def5 = hvo.getAttributeValue("def5"); // 重要性排序
            Map<String, Object> map = new HashMap<>();
            map.put("officedept", officedept);
            map.put("def5", def5);
            String pkPjappl = hvo.getPk_pjappl();
            map.put("pk_pjappl", pkPjappl);
            map.put("creationtime", hvo.getAttributeValue("creationtime"));
            if (hvo.getApprovestatus() == 1) {// 审批通过
                List<Map<String, Object>> listMaps = this.getListMaps(officedept, def5, map, pkPjappl);
                if (!listMaps.isEmpty()) {
                    for (Map<String, Object> lmap : listMaps) {
                        String pk_pjappl = lmap.get("pk_pjappl").toString();
                        Object o = lmap.get("def5");
                        if (pkPjappl.equals(pk_pjappl)) {
                            def5 = o;
                            hvo.setAttributeValue("def5", def5);
                            continue;
                        }else{
                            AggPjapplVO aggvo = this.getDaoUtils().findByPk(AggPjapplVO.class, pk_pjappl);
                            aggvo.getParentVO().setStatus(VOStatus.UPDATED);
                            aggvo.getParentVO().setAttributeValue("def5",o);
                            laggvos.add(aggvo);
                        }
                    }
                }
            }

        }
        if (!laggvos.isEmpty()){
            this.getDaoUtils().save(laggvos.toArray(new AggPjapplVO[0]), true);
        }
        this.getDaoUtils().save(vos, true);
    }

    @Override
    public void pjApplUnApprove(AggPjapplVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) return;
        List<AggPjapplVO> laggvos = new ArrayList<>();
        for (AggPjapplVO vo : vos) {
            PJApplHVO hvo = vo.getParentVO();
            hvo.setStatus(VOStatus.UPDATED);
            String officedept = hvo.getOfficedept();// 业务科室
            Object def5 = hvo.getAttributeValue("def5"); // 重要性排序
            if (hvo.getApprovestatus() == 2) {// 取消审批
                List<Map<String, Object>> lists = (List<Map<String, Object>>)this.getBaseDAO().executeQuery(
                        this.buildUnApproveOrderBySQL(officedept, def5), new MapListProcessor());
                if (lists.isEmpty()) {
                    continue;
                }
                for (Map<String, Object> map : lists) {
                    String pk_pjappl = map.get("pk_pjappl").toString();
                    Object new_index = map.get("new_index");
                    AggPjapplVO aggvo = this.getDaoUtils().findByPk(AggPjapplVO.class, pk_pjappl);
                    aggvo.getParentVO().setStatus(VOStatus.UPDATED);
                    aggvo.getParentVO().setAttributeValue("def5",new_index);
                    laggvos.add(aggvo);
                }

            }

        }

        if (!laggvos.isEmpty()){
            this.getDaoUtils().save(laggvos.toArray(new AggPjapplVO[0]), true);
        }

    }

    /**
     * 取消审批 构建 项目重要性排序了
     * @param officedept
     * @param index
     * @return
     * @throws BusinessException
     */
    protected String buildUnApproveOrderBySQL(String officedept,Object index) throws  BusinessException {
        StringBuilder sql = new StringBuilder();
        sql.append(" \tSELECT \n" );
        sql.append("     h.billno, \n" );
        sql.append("     h.PK_PJAPPL, \n" );
        sql.append("     h.officedept, \n" );
        sql.append("     h.def5, \n" );
        sql.append("     TO_NUMBER(h.def5) - 1 new_index, \n" );
        sql.append("     h.CREATIONTIME \n" );
        sql.append("  FROM \n" );
        sql.append("     HRPPL_PJAPPL h \n" );
        sql.append("  WHERE \n" );
        sql.append("     h.dr = 0 \n" );
        sql.append("     and h.def1 = 3 \n" );
        sql.append("     and h.approvestatus = 1 \n" );
        sql.append("     AND h.OFFICEDEPT = '"+officedept+"' \n" );
        Object def5 = 99999;
        if (index != null) {
            def5 = Integer.valueOf(index.toString());
        }
        sql.append("     and h.def5 > "+def5+" \n" );
        sql.append("  ORDER BY \n" );
        sql.append("  CASE \n" );
        sql.append("       WHEN h.def5 IS NOT NULL AND REGEXP_LIKE(h.def5, '^[0-9]+(\\.[0-9]+)?$') THEN TO_NUMBER(h.def5) \n" );
        sql.append("       ELSE 9999999999 END, \n" );
        sql.append("       h.CREATIONTIME ASC \n");

        return sql.toString();
    }
    /**
     * 业务归口科室
     * @param officedept
     * @return
     */
    protected  String buildApproveOrderBySQL(String officedept , String pkPjappl) {
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT \n" );
        sql.append("    h.PK_PJAPPL,\n" );
        sql.append("    h.officedept,\n" );
        sql.append("    h.def5, \n" );
        sql.append("    h.CREATIONTIME \n" );
        sql.append(" FROM \n" );
        sql.append("    HRPPL_PJAPPL h \n" );
        sql.append("  WHERE \n" );
        sql.append("    h.dr = 0  \n" );
        sql.append("    and h.approvestatus = 1  \n" );
        sql.append("    and h.def1 = 3 ");
        sql.append("    and  h.PK_PJAPPL <> '"+pkPjappl+"'  \n" );
        if(!"".equals(officedept)){
            sql.append(" and h.OFFICEDEPT = '"+officedept+"' ");
        }
        sql.append("  GROUP BY \n" );
        sql.append("    h.def5, \n" );
        sql.append("    h.CREATIONTIME, \n" );
        sql.append("    h.officedept, \n" );
        sql.append("    h.PK_PJAPPL \n" );
        sql.append("  order by   \n");
        sql.append("  CASE  ");
        sql.append("     WHEN h.def5 IS NOT NULL AND REGEXP_LIKE(h.def5, '^[0-9]+(\\.[0-9]+)?$') THEN TO_NUMBER(h.def5) ");
        sql.append("    ELSE 9999999999 END, ");
        sql.append("    h.CREATIONTIME ASC  ");
        return sql.toString();
    }


    /**
     * 获取ListMap
     * @param officedept
     * @param def5
     * @param map
     * @param pkPjappl
     * @return
     * @throws BusinessException
     */
    private List<Map<String,Object>> getListMaps(String officedept,Object def5, Map<String, Object> map,String pkPjappl) throws BusinessException{
        List<Map<String,Object>> lists = new ArrayList<>();

        // java 实现 List Map中 数据存在，pk,def1,其中def1存在数据是按照1，2，3的顺序进行排序，然后向List中新加 Map集合def1 为1,
        // 需要将原来的数据进行重排序,如果def1存在相同的数据依次往后排序
        List<Map<String,Object>> orders = (List<Map<String,Object>>)this.getBaseDAO().executeQuery(this.buildApproveOrderBySQL(officedept,pkPjappl), new MapListProcessor());
        if(orders.isEmpty()){
            map.put("def5",1);
            lists.add(map);
        }else {
            List<Map<String, Object>> isNotNull = new ArrayList<>();
            List<Map<String, Object>> isNull = new ArrayList<>();
            for (Map<String, Object> order : orders) {
                Object o = order.get("def5");
                if(o == null){
                    isNull.add(order);
                }else{
                    isNotNull.add(order);
                }
            }
            if(map.get("def5") == null ){
                isNull.add(map);
                isNull = ListMapSorter.processOrderCreationTime(isNull);
            }else {
                isNotNull = ListMapSorter.processList(isNotNull, map);
            }
            lists.addAll(isNotNull);
            int size = isNotNull.size();
            for (Map<String, Object> nullmap : isNull) {
                nullmap.put("def5",++size);
                lists.add(nullmap);
            }
        }

        return lists;
    }

    public BaseDAO getBaseDAO() {
        return this.baseDAO == null ? new BaseDAO() : this.baseDAO;
    }

    public DaoUtils getDaoUtils() {
        return this.dao ==  null ? new DaoUtils() : this.dao ;
    }
}
